package com.jin.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.jin.config.OssConfig;
import com.jin.service.CommonService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.LocalDate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import org.joda.time.DateTime;
import java.util.concurrent.TimeUnit;

/**
 * 通用服务实现类
 */
@Service
@Slf4j
public class CommonServiceImpl implements CommonService {

  @Autowired
  private OSS ossClient;

  @Autowired
  private OssConfig ossConfig;

  // 允许的图片格式
  private static final List<String> IMAGE_TYPE = Arrays.asList(".jpg", ".jpeg", ".png", ".bmp", ".gif", ".webp");

  @Override
  public String uploadFile(MultipartFile file) {
    // 1. 校验文件是否为空
    if (file == null || file.isEmpty()) {
      throw new RuntimeException("上传文件不能为空");
    }

    try {
      // 2. 获取文件名
      String originalFilename = file.getOriginalFilename();
      if (StringUtils.isBlank(originalFilename)) {
        throw new RuntimeException("上传文件名不能为空");
      }

      // 3. 生成新文件名（UUID方式）
      String fileName = generateFileName(originalFilename);

      // 4. 获取文件输入流
      InputStream inputStream = file.getInputStream();

      // 5. 获取文件大小
      long fileSize = file.getSize();

      // 6. 设置OSS对象元数据
      ObjectMetadata metadata = new ObjectMetadata();
      metadata.setContentLength(fileSize);
      metadata.setContentType(file.getContentType());

      // 7. 设置缓存策略
      metadata.setCacheControl("no-cache");
      metadata.setHeader("Pragma", "no-cache");

      // 8. 按日期生成文件路径，方便管理
      String fileHost = ossConfig.getFileHost();
      String dateTime = new DateTime().toString("yyyy/MM/dd");

      // 9. 构建完整的文件路径
      String fileUrl = fileHost + "/" + dateTime + "/" + fileName;

      // 10. 上传文件到OSS
      PutObjectResult result = ossClient.putObject(
          ossConfig.getBucketName(),
          fileUrl,
          inputStream,
          metadata);

      // 11. 上传成功，生成访问URL
      if (result != null) {
        // 生成公共访问URL（不带签名）
        String publicUrl = String.format("https://%s.%s/%s",
            ossConfig.getBucketName(),
            ossConfig.getEndpoint(),
            fileUrl);
        return publicUrl;
      }

      return null;
    } catch (IOException e) {
      log.error("文件上传失败：", e);
      throw new RuntimeException("文件上传失败: " + e.getMessage());
    }
  }

  @Override
  public String uploadImage(MultipartFile file) {
    // 1. 校验文件是否为空
    if (file == null || file.isEmpty()) {
      throw new RuntimeException("上传图片不能为空");
    }

    // 2. 校验文件是否为图片
    String originalFilename = file.getOriginalFilename();
    if (StringUtils.isBlank(originalFilename)) {
      throw new RuntimeException("上传文件名不能为空");
    }

    // 3. 校验文件格式
    String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
    if (!IMAGE_TYPE.contains(suffix)) {
      throw new RuntimeException("不支持的图片格式，仅支持jpg、jpeg、png、bmp、gif、webp格式");
    }

    // 4. 上传图片
    return uploadFile(file);
  }

  @Override
  public boolean deleteFile(String fileUrl) {
    try {
      // 获取文件路径（从URL中提取OSS中的对象名）
      String objectName = fileUrl;

      // 如果是完整URL，需要提取路径部分
      if (fileUrl.startsWith("http")) {
        // 移除域名和参数部分，只保留路径
        String endpoint = ossConfig.getEndpoint();
        String bucketName = ossConfig.getBucketName();

        // 移除前缀：https://bucket-name.endpoint/
        String domainPrefix = "https://" + bucketName + "." + endpoint + "/";
        if (fileUrl.startsWith(domainPrefix)) {
          objectName = fileUrl.substring(domainPrefix.length());
        }

        // 移除参数部分 ?xxx=yyy
        int paramIndex = objectName.indexOf("?");
        if (paramIndex > 0) {
          objectName = objectName.substring(0, paramIndex);
        }
      }

      // 执行删除操作
      ossClient.deleteObject(ossConfig.getBucketName(), objectName);
      return true;
    } catch (Exception e) {
      log.error("删除文件失败: ", e);
      return false;
    }
  }

  /**
   * 生成新文件名
   * 
   * @param originalFilename 原始文件名
   * @return 新文件名
   */
  private String generateFileName(String originalFilename) {
    // 获取文件后缀
    String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
    // 生成UUID作为文件名
    return UUID.randomUUID().toString().replace("-", "") + suffix;
  }
}
